package org.snail.employee.service.impl;

import com.dingtalk.open.client.api.model.corp.CorpUserDetail;
import lombok.extern.log4j.Log4j;
import org.snail.common.collection.CollectionUtil;
import org.snail.common.dingding.auth.AuthHelper;
import org.snail.common.dingding.user.UserHelper;
import org.snail.department.service.impl.DepartmentServiceImpl;
import org.snail.dept.bean.DepartDO;
import org.snail.employee.bean.EmployeesDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
@Log4j
public class EmployeesOptionService {

    @Autowired
    private EmployeesServiceImpl employeesService ;

    @Autowired
    private DepartmentServiceImpl departmentService ;

    /**
     * 获取部门下人员信息
     * 1、更新人员信息
     * 2、保存人员部门信息
     * @param departDO
     * @throws Exception
     */
    public void synchronizeUserByDepartment(DepartDO departDO) {
        try {
            log.info("synchronizeUserByDepartment : " + departDO);
            if (null == departDO || departDO.getId() < 1){
                log.error("同步部门消息的时候");
            } else {
                //从钉钉获取部门下最新人员情况
                List<CorpUserDetail> userDetailList = UserHelper.getAllUserDetails(AuthHelper.getAccessToken(), departDO.getId(), null);
                //获取数据库保存的人员情况
                List<String> userIdListFromDB = departmentService.findUserIdListByDeptId(departDO.getId());

                //更新数据、缓存中 用户对象和CorpUserDetail对象
                if (null!=userDetailList && !userDetailList.isEmpty()) {
                    synchronizeUser(userDetailList);
                }

                //同步部门和人员关系
                synchronizeDeptUser(departDO.getId(), userDetailList, userIdListFromDB);
            }
        } catch (Exception e) {
            log.error("从钉钉同步部门下人员信息出错", e);
        }
    }

    /**
     *  同步部门人员
     *  @param userDetailList
     *  @param userIdListFromDB
     */
    private void synchronizeDeptUser(Long id, List<CorpUserDetail> userDetailList, List<String> userIdListFromDB) throws Exception {

        //获取钉钉部门下人员ChatID
        Map<String, CorpUserDetail> userIdListFromApiMap = new HashMap<String, CorpUserDetail>();
        for (CorpUserDetail corpUserDetail : userDetailList) {
            if (StringUtils.isEmpty(corpUserDetail.getUserid())) {
                log.error("api中没有userid! 人员姓名：" + corpUserDetail.getName());
            } else {
                userIdListFromApiMap.put(corpUserDetail.getUserid(), corpUserDetail);
                log.info("departDO.getId(): " + id + ", corpUserDetail.getName():"  + corpUserDetail.getName());
            }
        }

        //需要删除的ID
        List<String> delUseridList = new ArrayList<String>();
        //需要添加的ID
        List<String> addUseridList = new ArrayList<String>();

        //Copy 一个副本
        Set<String> userIdListFromDBSet = new HashSet<String>();
        userIdListFromDBSet.addAll(userIdListFromDB);

        //Copy 一个副本
        Set<String> userIdListFromAPISet = new HashSet<String>();
        userIdListFromAPISet.addAll(userIdListFromApiMap.keySet());
        log.error("departDO.getId(): " + id + ", userIdListFromDBSet:" + userIdListFromDBSet);
        log.error("departDO.getId(): " + id + ", userIdListFromAPISet: " + userIdListFromAPISet);

        addUseridList.addAll(CollectionUtil.compareCollectionData(userIdListFromDBSet, userIdListFromAPISet));
        delUseridList.addAll(CollectionUtil.compareCollectionData(userIdListFromAPISet, userIdListFromDBSet));

        log.info("after departDO.getId(): " + id + ", addUseridList:" + addUseridList);
        log.info("after departDO.getId(): " + id + ", delUseridList: " + delUseridList);

        if (!addUseridList.isEmpty()) {
            departmentService.saveDeptUserList(id, addUseridList);
            log.error("==============================DB:新增部门人员：" + addUseridList);
        }
        if (!delUseridList.isEmpty()) {
            departmentService.deletDeptUserList(id, delUseridList);
            log.error("==============================DB:删除部门人员：" + delUseridList);
        }
    }

    /**
     *  同步人员信息到数据库和缓存
     *  @param userDetailList
     */
    private void synchronizeUser(List<CorpUserDetail> userDetailList) {
        if(null!=userDetailList && !userDetailList.isEmpty()) {
            //更新CorpUserDetail对象到缓存中
            employeesService.pushEmpToRedis(userDetailList);

            //更新数据、缓存中 用户对象
            for (CorpUserDetail corpUserDetail : userDetailList) {
                boolean isNeedUpdate = false;
                boolean isNeedInsert = false;

                //转换钉钉对象为EmployeesDO
                EmployeesDO employeesDO4Ding = employeesService.transCorpUserDetail2EmployeesDO(corpUserDetail);

                //用钉钉ID查询数据库
                EmployeesDO employeesDO4DB = employeesService.findEmpByDingId(corpUserDetail.getUserid());
                log.error("emp from dingding "+employeesDO4Ding+",emp from db"+employeesDO4DB);
                if(null!=employeesDO4DB && null!=employeesDO4Ding) {
                    isNeedUpdate = employeesService.compareEmpDBAndDing(employeesDO4DB, employeesDO4Ding);
                    if(isNeedUpdate) {
                        log.error("isNeedUpdate : " + isNeedUpdate + ", employeesDO4Ding:" + employeesDO4Ding);
                        log.info("isNeedUpdate : " + isNeedUpdate + ", employeesDO4DB:" + employeesDO4DB);
                    }
                } else if(null!=employeesDO4Ding){
                    //根据阿里工号、工号、名字中的一个获取对象
                    employeesDO4DB = employeesService.findEmpByNumOrName(employeesDO4Ding.getOutNum(), employeesDO4Ding.getWorkNum(), employeesDO4Ding.getName());
                    if(null!=employeesDO4DB) {
                        isNeedUpdate = employeesService.compareEmpDBAndDing(employeesDO4DB, employeesDO4Ding);
                        if(isNeedUpdate) {
                            log.error("isNeedUpdate : " + isNeedUpdate + ", employeesDO4Ding:" + employeesDO4Ding);
                            log.info("isNeedUpdate : " + isNeedUpdate + ", employeesDO4DB:" + employeesDO4DB);
                        }
                    } else {
                        isNeedInsert = true;
                        if(isNeedInsert) {
                            log.error("isNeedInsert : " + isNeedInsert + ", employeesDO4Ding:" + employeesDO4Ding);
                        }
                    }
                }

                if(null!=employeesDO4Ding && isNeedUpdate) {
                    employeesService.updateEmpFromDingding(employeesDO4Ding);
                } else if(null!=employeesDO4Ding && isNeedInsert) {
                    employeesService.InsertEmpFromDingding(employeesDO4Ding);
                }
            }
        }

    }


}
